package com.yeyaomai.dksns.flowis.dao.impl;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.mapreduce.GroupBy;
import org.springframework.data.mongodb.core.mapreduce.GroupByResults;
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
import org.springframework.data.mongodb.core.mapreduce.MapReduceResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Order;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Component;

import com.yeyaomai.dksns.flowis.dao.DetailDao;
import com.yeyaomai.dksns.flowis.dao.MongoDBBasicDao;
import com.yeyaomai.dksns.flowis.domain.flowisdetail.FlowisQueryOrder;
import com.yeyaomai.dksns.flowis.domain.flowisdetail.FlowisStatDetailDTO;
import com.yeyaomai.dksns.flowis.page.PageImplResult;
import com.yeyaomai.dksns.flowis.page.PageRequestOrder;
import com.yeyaomai.dksns.flowis.util.CollectionNames;
import com.yeyaomai.dksns.flowis.util.ListPropertyAndValueTool;

/**
 * 
 * @author dingtao@yeyaomai.com
 * 
 */

@Component
public class DetailDaoImpl extends MongoDBBasicDao<FlowisStatDetailDTO>
		implements DetailDao {

	private static Logger logger = LoggerFactory.getLogger(DetailDaoImpl.class);

	@Override
	public Page<FlowisStatDetailDTO> getSplit(FlowisQueryOrder order) {

		Query query = new Query();

		for (Map.Entry<String, String> entry : order.getSort().entrySet()) {
			query.sort().on(entry.getKey(), Order.valueOf(entry.getValue()));
		}

		List<String> includeFields = new ArrayList<String>();

		includeFields.add("ip");

		query.addCriteria(new Criteria("access_date").gt(order.getStartTime())
				.lt(order.getEndTime()));

		ListPropertyAndValueTool.querySaveCriteria(query, order,
				FlowisStatDetailDTO.class, includeFields);

		PageRequestOrder request = new PageRequestOrder(Integer.parseInt(order
				.getNumber()), order.getPageSize());

		long totalSize = getTotalSize(query, FlowisStatDetailDTO.class);

		query.skip(request.start()).limit(order.getPageSize());

		List<FlowisStatDetailDTO> ps = super.findList(query,
				FlowisStatDetailDTO.class);

		Page<FlowisStatDetailDTO> result = new PageImplResult<FlowisStatDetailDTO>(
				ps, request, totalSize);

		return result;
	}

	@Override
	public void insert(FlowisStatDetailDTO dto) {

		super.save(dto);
	}

	@Override
	public long getTotalSize(Query query, Class<FlowisStatDetailDTO> document) {
		return super.count(query, document);
	}

	@Override
	public List<FlowisStatDetailDTO> getLastNumberByCondition(
			LinkedHashMap<String, String> conditionArgs) {

		Query query = new Query();

		query.sort().on("access_date", Order.DESCENDING);

		for (Map.Entry<String, String> singleArg : conditionArgs.entrySet()) {
			query.addCriteria(new Criteria(singleArg.getKey()).is(singleArg
					.getValue()));
		}
		return super.findList(query, FlowisStatDetailDTO.class);
	}

	/**
	 * 分组统计方法
	 */
	@Override
	public GroupByResults<FlowisStatDetailDTO> groupFlowByTimeAndFunction(
			String mapFunction, String reduceFunction,String groupType, String from, String to) {
		// TODO Auto-generated method stub
		return super.group(Criteria.where("access_date").gte(from).lte(to),
				CollectionNames.FLOWISDETAIL,
				GroupBy.key(groupType).initialDocument(mapFunction)
						.reduceFunction(reduceFunction),
				FlowisStatDetailDTO.class);
	}

	@Override
	public <T> MapReduceResults<T> groupFlowByTimeAndFunction(
			Query query, String map, String reduce, MapReduceOptions options,Class<T> clas) {

		return mongoTemplate.mapReduce(query ,CollectionNames.FLOWISDETAIL ,map , reduce, options, clas);
	}

	@Override
	public <T> void delete(Query query, Class<T> clas) {

		mongoTemplate.remove(query, clas);
	}
}
